package com.hang.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hang.config.MsmConfig;
import com.hang.config.RedisConfig;

import com.hang.entity.User;
import com.hang.exception.MyException;
import com.hang.exception.MyExceptionEnum;
import com.hang.mapper.UserMapper;
import com.hang.mapstruct.UserMapStruct;
import com.hang.model.dto.request.LoginModel;
import com.hang.model.dto.response.UserInfoModel;
import com.hang.service.ILoginService;
import com.hang.service.IMsmService;
import com.hang.util.JwtUtil;
import com.hang.util.MD5;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@AllArgsConstructor
@Slf4j
public class LoginServiceImpl extends ServiceImpl<UserMapper, User>
        implements ILoginService {
    private UserMapper userMapper;

    private UserMapStruct userMapStruct;

    private RedisConfig redisConfig;

    private MsmConfig msmConfig;

    private IMsmService msmService;

    /**
     * 登录逻辑:
     *      直接根据职工号和密码查询出对象，若没有查询出来，那么就说明登录账号错误
     * @param loginModel
     * @return
     */
    @Override
    public Map<String, Object> loginByPwd(LoginModel loginModel) {
        if(ObjectUtils.isEmpty(loginModel)){
            throw new MyException(MyExceptionEnum.OBJECT_IS_NULL);
        }

        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper
                .lambda()
                .eq(User::getUserNo,loginModel.getUserNo())
                .eq(User::getPassword,MD5.encrypt(loginModel.getPassword()));

        User user = userMapper.selectOne(userQueryWrapper);

        if(ObjectUtils.isEmpty(user)){
            //用户不存在：账号密码不匹配
            throw new MyException(MyExceptionEnum.LOGIN_FAIL);
        }

        if(user.getUserStatus() == 0){
            //用户已被禁用，无法登录
            throw new MyException(MyExceptionEnum.USER_STATUS_CLOSE);
        }

        //验证登录成功,提取有效信息
        UserInfoModel userInfoModel = userMapStruct.userToUserInfoModel(user);

        Map<String,Object> map = new HashMap<>();

        String token = JwtUtil.createToken(user.getUserId(),user.getRealName());
        map.put("user",userInfoModel);
        //传入token令牌，后续需要提供令牌校验身份
        map.put("authorization",token);

        return map;
    }

    /**
     * 根据手机验证码登录账号
     * @param loginModel
     * @return
     */
    @Override
    public Map<String, Object> loginByTel(LoginModel loginModel) {
        RedisTemplate<String, Object> redisTemplate = redisConfig.getRedisTemplateByDb(0);

        String phone = loginModel.getPhone();
        String code = loginModel.getCode();

        if(StrUtil.isBlank(phone) || StrUtil.isBlank(code)){
            throw new MyException(MyExceptionEnum.MUST_FIELD_IS_NULL);
        }

        //判断手机对应的验证码是否正确
        Object codeObj = redisTemplate.opsForValue().get(phone);
        String dbCode = StrUtil.toString(codeObj);

        if(!dbCode.equals(code)){
            throw new MyException(MyExceptionEnum.CODE_ERROR);
        }

        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
        userQueryWrapper.lambda().eq(User::getPhone,phone);
        User user = userMapper.selectOne(userQueryWrapper);

        //用户状态是否禁用
        if(user.getUserStatus() == 0){
            throw new MyException(MyExceptionEnum.USER_STATUS_CLOSE);
        }

        //如果没有注销，那么就将登录信息存入
        UserInfoModel userInfoModel = userMapStruct.userToUserInfoModel(user);

        Map<String,Object> map = new HashMap<>();
        map.put("user",userInfoModel);

        String token = JwtUtil.createToken(user.getUserId(),user.getRealName());
        map.put("authorization",token);

        return map;
    }
}
